package com.hugui.stock.util;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hugui.stock.entity.StockKline;
import com.hugui.stock.entity.StockMarket;

/**
 * 腾讯股票API工具类
 * 替代新浪财经API获取A股数据
 */
public class TencentStockApiUtil {
    
    private static final Logger logger = LoggerFactory.getLogger(TencentStockApiUtil.class);
    
    /**
     * 获取股票K线数据
     * @param stockCode 股票代码（如：000001）
     * @param market 市场代码（sh或sz）
     * @param beginDate 开始日期
     * @param endDate 结束日期
     * @param days 天数
     * @return K线数据列表
     */
    public static List<StockMarket> getKlineData(String stockCode, String market, String beginDate, String endDate, String days) {
        List<StockMarket> stockMarketList = new ArrayList<>();
        
        try {
            // 腾讯股票API - 获取日K线数据
            String url = String.format("https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=%s%s,day,%s,%s,%s,qfq",
                market, stockCode, beginDate, endDate, days);
            
            String jsonResult = HttpClientUtil.get(url);
            if (jsonResult == null || jsonResult.isEmpty()) {
                logger.warn("获取股票{}数据失败，返回结果为空", stockCode);
                return stockMarketList;
            }
            
            JSONObject jsonObject = JSON.parseObject(jsonResult);
            if (jsonObject.getInteger("code") != 0) {
                logger.warn("获取股票{}数据失败，错误码：{}", stockCode, jsonObject.getInteger("code"));
                return stockMarketList;
            }
            
            JSONObject data = jsonObject.getJSONObject("data");
            if (data == null) {
                logger.warn("获取股票{}数据失败，data字段为空", stockCode);
                return stockMarketList;
            }
            
            String key = market + stockCode;
            JSONObject stockData = data.getJSONObject(key);
            if (stockData == null) {
                logger.warn("获取股票{}数据失败，股票数据为空", stockCode);
                return stockMarketList;
            }
            
            JSONArray dayLine = stockData.getJSONArray("qfqday");
            if (dayLine == null || dayLine.isEmpty()) {
                logger.warn("获取股票{}数据失败，日线数据为空", stockCode);
                return stockMarketList;
            }
            
            // 获取实时行情数据，包含交易金额和涨跌幅
            JSONObject qt = stockData.getJSONObject("qt");
            Long tradingAmount = null;
            Float priceLimit = null;
            
            if (qt != null) {
                JSONArray qtData = qt.getJSONArray(key);
                if (qtData != null && qtData.size() >= 35) {
                    try {
                        // 涨跌幅在第32个位置（索引31）
                        String priceLimitStr = qtData.getString(32);
                        if (priceLimitStr != null && !priceLimitStr.isEmpty()) {
                            priceLimit = Float.parseFloat(priceLimitStr);
                        }
                        
                        // 交易金额在第35个位置（索引34），格式为 "31.46/149739/470729432"
                        String tradingAmountStr = qtData.getString(35);
                        if (tradingAmountStr != null && !tradingAmountStr.isEmpty()) {
                            // 解析格式 "31.46/149739/470729432"，取最后一个数字
                            String[] parts = tradingAmountStr.split("/");
                            if (parts.length >= 3) {
                                tradingAmount = Long.parseLong(parts[2]);
                            }
                        }
                    } catch (NumberFormatException e) {
                        logger.warn("解析股票{}交易金额或涨跌幅数据失败：{}", stockCode, e.getMessage());
                    }
                }
            }
            
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            
            for (int i = 0; i < dayLine.size(); i++) {
                JSONArray dayData = dayLine.getJSONArray(i);
                if (dayData.size() >= 6) {
                    try {
                        String dateStr = dayData.getString(0);
                        Date tradingDate = sdf.parse(dateStr);
                        
                        StockMarket stockMarket = StockMarket.builder()
                            .stockCode(stockCode)
                            .tradingDate(tradingDate)
                            .open(new BigDecimal(dayData.getString(1)))
                            .close(new BigDecimal(dayData.getString(2)))
                            .high(new BigDecimal(dayData.getString(3)))
                            .low(new BigDecimal(dayData.getString(4)))
                            .tradingVolume(new Double(dayData.getString(5)).longValue())
                            .build();

                        if(endDate.equals(dateStr)){
                            stockMarket.setPriceLimit(priceLimit);
                            stockMarket.setTradingAmount(tradingAmount);
                        }

                        stockMarketList.add(stockMarket);
                    } catch (ParseException e) {
                        logger.error("解析股票{}日期数据失败：{}", stockCode, e.getMessage());
                    } catch (NumberFormatException e) {
                        logger.error("解析股票{}数值数据失败：{}", stockCode, e.getMessage());
                    }
                }
            }
            
        } catch (Exception e) {
            logger.error("获取股票{}数据异常：{}", stockCode, e.getMessage(), e);
        }
        
        return stockMarketList;
    }
    
    /**
     * 计算均线数据
     * @param stockMarketList 股票市场数据列表
     * @return 均线数据
     */
    public static StockKline calculateKlineData(List<StockMarket> stockMarketList) {
        if (stockMarketList == null || stockMarketList.size() < 30) {
            return null;
        }
        
        // 按日期排序，最新的在前面
        stockMarketList.sort((a, b) -> b.getTradingDate().compareTo(a.getTradingDate()));
        
        BigDecimal k5 = BigDecimal.ZERO;
        BigDecimal k10 = BigDecimal.ZERO;
        BigDecimal k20 = BigDecimal.ZERO;
        BigDecimal k30 = BigDecimal.ZERO;
        
        // 计算30日均线
        for (int i = 0; i < 30 && i < stockMarketList.size(); i++) {
            k30 = k30.add(stockMarketList.get(i).getClose());
        }
        
        // 计算20日均线
        for (int i = 0; i < 20 && i < stockMarketList.size(); i++) {
            k20 = k20.add(stockMarketList.get(i).getClose());
        }
        
        // 计算10日均线
        for (int i = 0; i < 10 && i < stockMarketList.size(); i++) {
            k10 = k10.add(stockMarketList.get(i).getClose());
        }
        
        // 计算5日均线
        for (int i = 0; i < 5 && i < stockMarketList.size(); i++) {
            k5 = k5.add(stockMarketList.get(i).getClose());
        }
        
        // 计算平均值
        k30 = k30.divide(new BigDecimal(30), 3, BigDecimal.ROUND_HALF_DOWN);
        k20 = k20.divide(new BigDecimal(20), 3, BigDecimal.ROUND_HALF_DOWN);
        k10 = k10.divide(new BigDecimal(10), 3, BigDecimal.ROUND_HALF_DOWN);
        k5 = k5.divide(new BigDecimal(5), 3, BigDecimal.ROUND_HALF_DOWN);
        
        return StockKline.builder()
            .stockCode(stockMarketList.get(0).getStockCode())
            .k5(k5)
            .k10(k10)
            .k20(k20)
            .k30(k30)
            .tradingDate(new Date())
            .build();
    }
} 